package edu.olin.scheduler.loader;

import edu.olin.scheduler.common.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;

public class CourseLoader {
    
    private static int line = 0;
    public static int getLine(){ return line; }
    
    public static Category loadCoursesFromFile(String file) throws ParseException {
        return loadCourses(loadFile(file));
        }
    
    public static Category loadCoursesFromResource(String path) throws ParseException {
        return loadCourses(loadFileResource(path));
        }
    
    private static Category loadCourses(ArrayList<String> lines) throws ParseException {
        if(lines==null){ return null; }
        Iterator<String> itr = lines.iterator();
        line = 0;
        Category root = buildCategory(itr,"Olin College, 2007 Spring");
        return root;
        }
    
    private static Category buildCategory(Iterator<String> itr, String name) throws ParseException {
        Category cat = new Category(name,null);
        while(itr.hasNext()){
            line++; String next = itr.next();
            String[] parts = next.split("\t");
            if(parts==null||parts.length==0){ continue; }//bad line?
            if(parts.length==1 && parts[0].equals("end")){ return cat; }
            if(parts[0].equals("school")||parts[0].equals("term")){ continue; }
            if(parts.length==2 && parts[0].equals("category")){
                cat.addChild(buildCategory(itr, parts[1]));
                continue;
                }
            if(parts.length==4 && parts[0].equals("course")){
                buildCourse(itr,cat,parts[1],parts[2],parts[3]);
                continue;
                }
            throw new ParseException("Encountered an invalid liner ["+next+"]");
            }
        return cat;
        }
    
    private static Category buildCourse(Iterator<String> itr, Category cat, String number, String name, String credits) throws ParseException {
        ArrayList<Course> sections = new ArrayList();
        while(itr.hasNext()){
            line++; String next = itr.next();
            String[] parts = next.split("\t");
            if(parts==null){ continue; }//ignore bad lines
            if(parts.length==1 && parts[0].equals("end")){ break; }
            if(parts.length>=3 && parts[0].equals("section")){
                Meeting[] meetings = new Meeting[parts.length-2];
                for(int i=2; i<parts.length; i++){
                    meetings[i-2] = MeetingLoader.getMeeting(parts[i]);
                    }
                Course c = new Course(name,number,4.0,"",meetings);
                c.setSection(parts[1]);
                sections.add(c);
                continue;
                }
            throw new ParseException("Encountered an invalid line");
            }
        if(sections.size()==0){ throw new ParseException("Courses must contain at least one section"); }
        if(sections.size()>1){ //create a category for the Course and put each subsection as a different cours
            Category nc = new Category(name,cat);
            cat.addChild(nc);
            nc.isCourse = true; //this Category represents a Course
            cat=nc;
            }
        Iterator<Course> secitr = sections.iterator();
        while(secitr.hasNext()){ Course c = secitr.next(); cat.addChild(c); c.setCategory(cat); }
        return cat;
        }
    
    private static ArrayList<String> loadFile(String file) throws ParseException {
        BufferedReader r = null;
        try{
            r = new BufferedReader(new FileReader(file));
            return loadFile(r);
            }catch(Exception e){ throw new ParseException("Could not read file: "+e); }
        }
    
    private static ArrayList<String> loadFileResource(String path) throws ParseException {
        try{
            BufferedReader r = new BufferedReader(new InputStreamReader(ResourceLoader.getResourceStream(path)));
            return loadFile(r);
            }catch(Exception e){ throw new ParseException("Could not read from text resource: "+e); }
        }
    
    private static ArrayList<String> loadFile(BufferedReader r) throws ParseException {
        try{
            ArrayList<String> lines = new ArrayList();
            String line = null;
            while( (line=r.readLine()) != null ){
                lines.add(line.trim());
                }
            r.close();
            return lines;
        }catch(Exception e){e.printStackTrace();throw new ParseException("Could not read file: "+e);}
        }
    
    }